home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / MPW_TOOL / TOOLS / TOOLS_WI / ICON_8 / MEMMON_F / MMPS.C < prev    next >
Text File  |  1990-03-02  |  8KB  |  273 lines

  1. /*
  2.  * mmps.c: batch mode PostScript translator.
  3.  *
  4.  *  We define and use four general procedures:
  5.  *    oldy oldx y x n -R- y x+n+1    % n by H rectangle at (x,y), set x & y
  6.  *    oldy oldx n -A- oldy oldx+n+1    % n by H rectangle adjacent, update x
  7.  *    oldy oldx -V- oldy oldx        % 1 by H rectangle at left, no change
  8.  *    text x y -S- --            % text string at (x,y)
  9.  *  We also define a Cnn procedure for each different color used.
  10.  *
  11.  *  "S" is straightforward and simply displays a text string.  The other three
  12.  *  general procedures work together to fill rectangles.  They maintain current
  13.  *  y and x values atop the PostScript stack.  x is atop y for easiest access.
  14.  *
  15.  *  "R" draws an n-wide block at (x,y), leaving (x+n+1, y) on the stack.  The +1
  16.  *  allows for the usual one-pixel gap between blocks on the display.
  17.  *
  18.  *  "A" draws an n-wide block adjacent to the last block, updating the stack
  19.  *  similarly.
  20.  *
  21.  *  "V" draws a 1-wide block to the LEFT of the stack location, leaving it
  22.  *  unchanged.  This is designed for drawing string-region separators.
  23.  */
  24.  
  25. #include "memmon.h"
  26.  
  27. hidden novalue rect Params((int c, int x, int y, int n));
  28. hidden novalue pscolor Params((int c));
  29.  
  30. #define PageHeight 792            /* default dimensions */
  31. #define PageWidth 612
  32. #define SideMargin 72            /* 1" margin at top and sides */
  33. #define TopMargin 72
  34. #define BotMargin 96            /* larger at bottom for QMS color ptr */
  35. #define MaxHeight (PageHeight - TopMargin - BotMargin)
  36. #define MaxWidth (PageWidth - 2 * SideMargin)
  37. #define FrameWidth 1            /* frame surrounding dimensions above */
  38.  
  39. #define Font "Helvetica"
  40. #define CharHeight (3 * textrow / 4)    /* height of a text char */
  41. #define CharBase   (textrow / 4)    /* offset to baseline within text box */
  42.  
  43. static int llx, lly, urx, ury;        /* bounding box including frame */
  44. static int xcur, ycur;            /* current y, x on PostScript stack */
  45. static float psscale;            /* output scaling */
  46. static int lastpscolor = -1;        /* last color command output */
  47.  
  48. /*
  49.  * devsetup() - set globals to device-dependent values.
  50.  */
  51. novalue devsetup()
  52.    {
  53.    granularity = 4;
  54.    width = MaxWidth;
  55.    height = MaxHeight;
  56.    textrow = 11;
  57.    textsep = 2;
  58.    memrow = 20;
  59.    batchmode = 1;
  60.    }
  61.  
  62. /*
  63.  * devinit() - initialize output file.
  64.  */
  65. novalue devinit()
  66.    {
  67.    char time_buf[26];
  68.    int fwidth, fheight, i;
  69.  
  70.    fheight = height + 2 * FrameWidth;        /* dimensions including frame */
  71.    fwidth = width + 2 * FrameWidth;
  72.  
  73.    psscale = 1.0;
  74.    if (width > MaxWidth)
  75.       psscale = (MaxWidth) / (float)width;
  76.    if (psscale * height > MaxHeight)
  77.       psscale *= (MaxHeight) / (psscale * height);
  78.    llx = (PageWidth - psscale * fwidth) / 2;
  79.    lly = PageHeight - TopMargin - psscale * fheight;
  80.    urx = llx + psscale * fwidth + 0.999;
  81.    ury = lly + psscale * fheight + 0.999;
  82.  
  83.    getctime(time_buf);
  84.    printf("%%!PS-Adobe-2.0 EPSF-1.2\n");
  85.    if (title)
  86.       printf("%%%%Title: %s\n", title);
  87.    printf("%%%%Creator: mmps\n");
  88.    printf("%%%%CreationDate: %s", time_buf);
  89.    printf("%%%%DocumentFonts: %s\n", Font);
  90.    printf("%%%%BoundingBox: %d %d %d %d\n", llx, lly, urx, ury);
  91.    printf("%%%%EndComments\n");
  92.    /*
  93.     * define general-purpose PostScript procedures
  94.     */
  95.    printf("/R { 5 3 roll pop pop 3 copy add exch moveto 0 H rlineto\n");
  96.    printf("     dup neg 0 rlineto 0 H neg rlineto fill add 1 add } bind def\n");
  97.    printf("/A { 3 copy add exch moveto 0 H rlineto\n");
  98.    printf("     dup neg 0 rlineto 0 H neg rlineto fill add 1 add } bind def\n");
  99.    printf("/V { 2 copy exch moveto 0 H rlineto\n");
  100.    printf("     -1 0 rlineto 0 H neg rlineto fill } bind def\n");
  101.    printf("/S { moveto show } bind def\n");
  102.    /*
  103.     * define a procedure for each unique color
  104.     */
  105.    for (i = 0; i < NColors; i++)
  106.       if (cmap[i].uniq == i)            /* if first occurrence */
  107.          printf("/C%d { %.2f %.2f %.2f setrgbcolor } bind def\n", i,
  108.             cmap[i].red / 255.0, cmap[i].green / 255.0, cmap[i].blue / 255.0);
  109.    printf("%%%%EndProlog\n");
  110.    }
  111.  
  112. /*
  113.  * batbegin() - prepare to write an image.
  114.  */
  115. novalue batbegin()
  116.    {
  117.    static int pageno = 0;
  118.    int x;
  119.    float yscale;
  120.  
  121.    ++pageno;
  122.    lastpscolor = -1;
  123.  
  124.    /* initialize for a new page */
  125.    printf("%%%%Page: %d %d\n", pageno, pageno);
  126.    printf("save\n");
  127.    if (sfreq != 0)
  128.       printf("currentscreen 3 -1 roll pop %d 3 1 roll setscreen\n", sfreq);
  129.  
  130.    /* scale according to global parameters set up earlier */
  131.    printf("%d %d translate\n", llx, lly);
  132.    printf("%f %f scale\n", psscale, psscale);
  133.    printf("%d %d translate\n", FrameWidth, FrameWidth);    /* move inside border */
  134.  
  135.    /* tweak the scaling a little more to fill up unused space at the bottom */
  136.    yscale = (float)(height + 2 * FrameWidth) / (height - ymin + 2 * FrameWidth);
  137.    printf("0 %d translate\n", height + FrameWidth);
  138.    printf("1.0 %f scale\n", yscale);
  139.    printf("0 %d translate\n", -height - FrameWidth);
  140.  
  141.    /* draw the background, a rectangle with the last partial line reomved */ 
  142.    pscolor(C_Background);
  143.    printf("\n");
  144.    x = mempixels % width;
  145.    if (x == 0)
  146.       x = width;
  147.    printf("%d %d moveto %d %d lineto %d %d lineto %d %d lineto\n",
  148.       -FrameWidth, ymin - FrameWidth,
  149.       -FrameWidth, height + FrameWidth,
  150.       width + FrameWidth, height + FrameWidth,
  151.       width + FrameWidth, ymin - FrameWidth + memrow);
  152.    printf("  %d %d lineto %d %d lineto fill\n",
  153.       x + FrameWidth, ymin - FrameWidth + memrow,
  154.       x + FrameWidth, ymin - FrameWidth);
  155.  
  156.    /* finish initialization */
  157.    printf("1 setlinewidth\n");
  158.    if (textrow > 0) {
  159.       printf("/%s findfont [%.3f 0 0 %.3f 0 0] makefont setfont\n", Font,
  160.          1.9 * (float)width / (float)TextLength, (float)CharHeight);
  161.       printf("/H %d def\n", textrow - 1);
  162.       }
  163.    printf("0 0\n");        /* initial y,x for the PostScript stack */
  164.    xcur = ycur = 0;
  165.    }
  166.  
  167. /*
  168.  * battext(s, row, col, fg, bg) - output text string.
  169.  */
  170. novalue battext(s, row, col, fg, bg)
  171. char *s;
  172. int row, col, fg, bg;
  173.    {
  174.    float charwidth;
  175.    int x, xx, y;
  176.  
  177.    charwidth = (float)width / (float)TextLength;
  178.    x = charwidth * col;
  179.    xx = charwidth * (col + strlen(s) + 1);
  180.    y = height - (row + 1) * textrow + 1;
  181.    rect(bg, x, y, xx - x - 1);
  182.    pscolor(fg);
  183.    pstext(s);
  184.    printf(" %d %d S\n", (int)(x + charwidth / 2), y + CharBase);
  185.    }
  186.  
  187. /*
  188.  * batmem(mbuf) - output memory image.
  189.  */
  190. novalue batmem(mbuf)
  191. unsigned char mbuf[];
  192.    {
  193.    int c, d, n, x, y;
  194.    unsigned char *p, *endrow, *endmem;
  195.  
  196.    if (memrow > 1)
  197.       printf("/H %d def\n", memrow - 1);    /* define row height */
  198.    else
  199.       printf("/H 1 def\n");
  200.  
  201.    /*
  202.     * identify contiguous blocks of color
  203.     * (assumes we can skip the separator pixel between two blocks)
  204.     */
  205.    p = mbuf;
  206.    endmem = mbuf + mempixels;
  207.    y = memheight;
  208.    while (p < endmem)  {
  209.       endrow = p + width;
  210.       if (endrow > endmem)
  211.          endrow = endmem;
  212.       x = -1;
  213.       y -= memrow;
  214.       while (p < endrow) {
  215.          c = *p++;
  216.          x++;
  217.          if (c == C_Bsep)
  218.             continue;
  219.          n = 1;
  220.          while (p < endrow && (d = *p++) == c)
  221.             n++;
  222.          rect(c, x, y, n);        /* fill rectangle with color c */
  223.          x += n;
  224.          if (d != C_Bsep && p < endrow)
  225.             p--, x--;
  226.          }
  227.       }
  228.  
  229.    printf("pop pop restore showpage\n");
  230.    }
  231.  
  232. /*
  233.  * batterm() - terminate entire run.
  234.  */
  235. novalue batterm()
  236.    {
  237.    printf("%%%%Trailer\n");
  238.    }
  239.  
  240. /*
  241.  * rect(c,x,y,n) - fill an H by n rectangle at (x,y) with color c.
  242.  */
  243. static novalue rect(c, x, y, n)
  244. int c, x, y, n;
  245.    {
  246.    pscolor(c);
  247.    if ((n == 1) && (x == xcur - 1) && (y == ycur))
  248.       printf("V\n");
  249.    else if ((x == xcur) && (y == ycur)) {
  250.       printf("%d A\n", n);
  251.       xcur = x + n + 1;
  252.       }
  253.    else {
  254.       printf("%d %d %d R\n", y, x, n);
  255.       xcur = x + n + 1;
  256.       ycur = y;
  257.       }
  258.    }
  259.  
  260. /*
  261.  * pscolor(c) - write a setcolor command for color c,
  262.  *  if it's not the same as the last one.
  263.  */
  264. static novalue pscolor(c)
  265. int c;
  266.    {
  267.    c = cmap[c].uniq;
  268.    if (lastpscolor == c)
  269.       return;
  270.    printf("C%d ", c);
  271.    lastpscolor = c;
  272.    }
  273.